<template>
  <div class="role-view" v-loading="saveLoading">
    <el-row :gutter="10">
      <el-col :span="16">
        <div class="box">
          <div class="flex mb-4 mt-2">
            <el-button
              type="primary"
              icon="Plus"
              size="small"
              @click="addRoleDialog.show()"
            >
              新增
            </el-button>
            <el-button
              type="danger"
              icon="Delete"
              size="small"
              :disabled="selectedData.length === 0"
              @click="handleDelete()"
            >
              删除
            </el-button>
          </div>
          <Table :data="tableData" @selectionChange="handleSelectionChange">
            <TableColumn label="编号" prop="id" />
            <TableColumn
              label="角色名"
              prop="name"
              :min-width="getColumnWidth(tableData, 'name', 80)"
            />
            <TableColumn
              label="标识符"
              prop="code"
              :min-width="getColumnWidth(tableData, 'code', 80)"
            />
            <TableColumn label="描述" prop="remark" show-overflow-tooltip />
            <TableColumn label="操作" width="250px">
              <template #default="{ row }">
                <el-button
                  type="success"
                  size="small"
                  @click="handleCurrentChange(row)"
                >
                  分配权限
                </el-button>
                <el-button
                  type="primary"
                  size="small"
                  @click="addRoleDialog.show(row)"
                >
                  编辑
                </el-button>
                <el-button
                  type="danger"
                  icon="Delete"
                  size="small"
                  @click="handleDelete(row)"
                >
                  删除
                </el-button>
              </template>
            </TableColumn>
          </Table>
          <Pagination
            v-model:current-page="page.currentPage"
            v-model:page-size="page.pageSize"
            :total="page.total"
            @size-change="getInfo"
            @current-change="getInfo"
          />
        </div>
      </el-col>
      <el-col :span="8">
        <div class="box">
          <div class="flex justify-between items-center p-2 border-b">
            <div class="text-xl">菜单/权限分配</div>
            <div class="flex">
              <el-button
                text
                type="primary"
                size="small"
                :disabled="!currentRow.id"
                @click="setAllTreeCheck"
              >
                全选
              </el-button>
              <el-button
                type="primary"
                size="small"
                :disabled="!currentRow.id"
                @click="saveRoleMenu()"
              >
                保存
              </el-button>
            </div>
          </div>
          <el-scrollbar v-if="currentRow.id" max-height="calc(100vh - 300px)">
            <el-tree
              ref="treeRef"
              class="pt-1"
              style="max-width: 600px"
              :props="treeProps"
              :data="treeData"
              node-key="id"
              show-checkbox
              check-strictly
            />
          </el-scrollbar>
        </div>
      </el-col>
    </el-row>
    <AddRoleDialog
      ref="addRoleDialog"
      :power-type="queryData.type"
      @update="getInfo"
    />
  </div>
</template>

<script setup lang="ts">
import { onMounted, reactive, ref, useTemplateRef } from 'vue'
import Table from '@/components/table/Table.vue'
import { PageParam } from '@/type'
import {
  deleteRole,
  getRoleList,
  getRoleMenu,
  updateRoleMenu,
} from '@/api/sys/role'
import Pagination from '@/components/Pagination.vue'
import TableColumn from '@/components/table/TableColumn.vue'
import { getMenuList } from '@/api/sys/menu'
import { ElMessageBox, TreeInstance } from 'element-plus'
import { hideLoading, showLoading } from '@/plugins/loading'
import AddRoleDialog from '@/views/sys/role/AddRoleDialog.vue'
import useUserStore from '@/stores/user'
import { getColumnWidth } from '@/plugins/util'
import useRoleStore from '@/stores/role'
import { Message } from '@/hooks/message'

const treeRef = useTemplateRef<TreeInstance>('treeRef')
const addRoleDialog =
  useTemplateRef<InstanceType<typeof AddRoleDialog>>('addRoleDialog')

const userStore = useUserStore()

const queryData = reactive({
  type: '2',
})

const saveLoading = ref(false)
const selectedData = ref([])
const currentRow = ref({ id: undefined })
const tableData = ref([])

const page = reactive({
  currentPage: 1,
  pageSize: 20,
  total: 0,
})

const treeData = ref([])

const treeProps = {
  label: 'name',
}

function handleSelectionChange(val: any[]) {
  selectedData.value = val
}

function setAllTreeCheck() {
  treeRef.value.setCheckedKeys(getAllId())
}

function getAllId(tree = treeData.value) {
  const ids = []
  for (const item of tree) {
    if (!item.disabled) {
      ids.push(item.id)
    }
    if (item.children) {
      ids.push(...getAllId(item.children))
    }
  }
  return ids
}

function handleDelete(row?: any) {
  let text: string
  if (row.name) {
    text = `确定要删除 ${row.name} 吗？`
  } else {
    text = `确定要删除选中的 ${selectedData.value.length} 条数据吗？`
  }
  ElMessageBox.confirm(text, '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  })
    .then(async () => {
      let ids: string
      showLoading()
      if (row && row.name) {
        ids = row.id
      } else {
        ids = selectedData.value.map((item) => item.id).join(',')
      }
      const { data } = await deleteRole(ids)
      if (data.status === 200) {
        Message({
          message: data.message,
          type: 'success',
        })
      }
      hideLoading()
      getInfo()
    })
    .catch(() => {})
}

async function saveRoleMenu() {
  saveLoading.value = true
  const postData = {
    id: currentRow.value.id,
    menuIds: treeRef.value.getCheckedKeys().join(','),
  }
  const { data } = await updateRoleMenu(postData)
  if (data.status === 200) {
    Message({
      message: data.message,
      type: 'success',
    })
    treeRef.value.setCheckedKeys([])
    currentRow.value = {
      id: undefined,
    }
    getInfo()
    saveLoading.value = false
  }
}

async function handleCurrentChange(row: any) {
  currentRow.value = row
  if (row && row.id) {
    showLoading()
    const { data } = await getRoleMenu(row.id)
    if (data.status === 200) {
      treeRef.value.setCheckedKeys(
        data.data.map((item: any) => item.id),
        true,
      )
    }
    hideLoading()
  }
}

async function getRoleTree() {
  const pageParam: PageParam<typeof queryData> = {
    currentPage: page.currentPage,
    pageSize: page.pageSize,
    query: queryData,
    sort: [],
  }
  const { data } = await getRoleList(pageParam)
  if (data.status === 200) {
    tableData.value = data.data.data
    page.total = data.data.totalCount
  }
}

function resetRoleStore() {
  const roleStore = useRoleStore()
  if (queryData.type === '1') {
    roleStore.getWxRole()
  } else if (queryData.type === '2') {
    roleStore.getManageRole()
  }
}

async function getMenuTree() {
  const { data } = await getMenuList(queryData)
  if (data.status === 200) {
    treeData.value = data.data
  }
}

function getInfo() {
  currentRow.value = { id: undefined }
  getRoleTree()
  getMenuTree()
  resetRoleStore()
}

function reset() {
  Object.assign(queryData, {
    type: '1',
    unitId: userStore.unitId,
  })
  getInfo()
}

onMounted(() => {
  getInfo()
})
</script>

<style scoped lang="scss">
.box {
  @apply py-2 px-4;
  @apply bg-white rounded-md shadow-md;
  @apply border;
  min-height: calc(100vh - 220px);
}
</style>
